package com.lanyou.cook.camel.util;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.model.MulticastDefinition;
import org.apache.camel.model.RouteDefinition;

import com.google.gson.Gson;
import com.lanyou.cook.camel.datadictionary.KettleJobScheduleCycleUnit;
import com.lanyou.cook.camel.entity.FileFilterJson;
import com.lanyou.cook.camel.entity.Ftp;
import com.lanyou.cook.camel.entity.FtpServer;
import com.lanyou.cook.camel.entity.TesbBuIfSchedule;
import com.lanyou.cook.camel.service.impl.AuthServiceImpl;
import com.lanyou.cook.camel.service.impl.LogServiceImpl;

/**
 * FTP路由创建类，创建与接口相对应的FTP路由
 * 
 * @author ly-lihailang
 *
 */
public class FTPCamelRouteBuilder extends RouteBuilder {
	/**
	 * 一个ftp接口的全部ftp服务
	 */
	private List<FtpServer> ftpServersList;
	/**
	 * 一个ftp接口对应的定时任务
	 */
	private TesbBuIfSchedule buIfSchedule;
	/**
	 * 要创建路由的ftp接口
	 */
	private Ftp ftp;
	private AuthServiceImpl authServiceImpl;
	private LogServiceImpl logServiceImpl;
	
	
	
	

	public FTPCamelRouteBuilder() {
		super();
	}

	/**
	 * @param ftpServerList
	 *            this.ftpServerList
	 * @param buIfSchedule
	 *            this.buIfSchedule
	 * @param ftp
	 *            this.ftp
	 */
	public FTPCamelRouteBuilder(List<FtpServer> ftpServerList,
			TesbBuIfSchedule buIfSchedule, Ftp ftp) {
		this.ftpServersList = ftpServerList;
		this.buIfSchedule = buIfSchedule;
		this.ftp = ftp;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.apache.camel.builder.RouteBuilder#configure()
	 */
	@Override
	public void configure() throws Exception {
		// 存放源ftp服务
		List<FtpServer> fromServerList = new ArrayList<FtpServer>();
		// 存放目标ftp服务
		List<FtpServer> toServerList = new ArrayList<FtpServer>();
		// 遍历ftpServersList，分类出源、目标ftp服务
		for (FtpServer ftpServer : this.ftpServersList) {
			if (ftpServer.getHostType().equals("1")) {// 如果类型为：1，则为源ftp服务
				fromServerList.add(ftpServer);
			} else if (ftpServer.getHostType().equals("2")) {// 如果类型为：2，则为目标ftp服务
				toServerList.add(ftpServer);
			}
		}

		int processOrderIndex = 0;
		int processOrderIndexto = 0;
		// int processQutIndex=0;
		// 遍历源ftp服务，根据源ftp创建路由
		for (FtpServer fromServer : fromServerList) {
			if (buIfSchedule != null) {
				// from("quartz2://checkFtp"+processQutIndex+"?cron="+createTimer(buIfSchedule)).bean(logServiceImpl,"checkFTP("+this.ftp.getCode()+","+this.ftp.getName()+","+fromServer.getId()+")");
				// processQutIndex++;
			} else {
				// from("direct:start"+processQutIndex).bean(logServiceImpl,"checkFTP("+this.ftp.getCode()+","+this.ftp.getName()+","+fromServer.getId()+")");
				logServiceImpl.checkFTP(ftp.getCode(), ftp.getName(),
						fromServer.getId());
				// processQutIndex++;
			}
			// 定义路由
			RouteDefinition definition1 = null;
			// 创建路由的from
			definition1 = from(getFtpUri(fromServer)).errorHandler(
					deadLetterChannel("direct:fromErr" + fromServer.getId()));
			// 创建路由的multicast
			MulticastDefinition multicast = definition1.multicast();
			// 根据目标ftp的个数创建pipeline
			for (int i = 0; i < toServerList.size(); i++) {
				multicast.pipeline("direct:processOrder" + processOrderIndex);
				processOrderIndex++;
			}
			// 创建pipeline具体执行的路由
			for (FtpServer toServer : toServerList) {
				// 创建与目标ftp相匹配的路由：格式为from(direct:processOrderj).bean(authServiceImpl,methoduri).to(toftpuri).bean(logServiceImpl,methoduri)
				// 其中from(direct:processOrderj)对应上面pipeline中的direct:processOrderi
				from("direct:processOrder" + processOrderIndexto)
						.bean(authServiceImpl,
								getBeanMethod("authResult", fromServer,
										toServer))
						.to(getFtpUri(toServer))
						.errorHandler(
								deadLetterChannel("direct:toErr"
										+ fromServer.getId() + toServer.getId()))
						.bean(logServiceImpl,
								getBeanMethod("writeLog", fromServer, toServer));
				processOrderIndexto++;
				// CamelFactory.routeMap.get(ftp.getCode()).put(fromServer.getId()+toServer.getId(),
				// "start");
			}
			// from("direct:fromErr" + fromServer.getId()).bean(logServiceImpl,
			// getBeanMethod("writeErrLog", fromServer));
			//
			// 创建异常处理
			for (FtpServer toServer : toServerList) {
				// 创建异常处理路由：格式为from(direct:toErrj).bean(authServiceImpl,methoduri)
				// 其中from(direct:toErr)对应上面ERR路由中的direct:processErrj
				from("direct:toErr" + fromServer.getId() + toServer.getId())
						.bean(logServiceImpl,
								getBeanMethod("writeErrLog", fromServer,
										toServer));
			}

		}
	}

	/**
	 * 根据ftp服务生成对应ftp路由的uri
	 * 
	 * @param ftpServer
	 *            ftp服务
	 * @return 对应ftp服务的uri
	 */
	public String getFtpUri(FtpServer ftpServer) {
		
		String ftpMode ;//PropFactory.getPropByKey(Constants.FTP_MODE_TYPE);
		
//		if(StringUtils.isBlank(ftpMode)){
//			ftpMode = "true";
//		}
		
		if("1".equals(ftpServer.getPassiveMode())){
			ftpMode = "true";
		}else{
			ftpMode = "false";
		}

		String ftpUri = "";
		// 判断ftp服务类型
		if (ftpServer.getHostType().equals("1")) {// 如果是源ftp服务，则创建源ftp服务的uri
			// 判断ftp的登录方式
			if (ftpServer.getIsAnonymous().equals("0")) {// 如果是非匿名登录，则生成含有password的uri
				// uri的样式如："ftp://lhlang@172.26.142.126:21?password=111111&localWorkDirectory=E:/temp/&scheduler=quartz2&scheduler.cron=0/10 * * * * ?&fileName=report.txt&binary=true"
				ftpUri = "ftp://" + ftpServer.getUserName() + "@"
						+ ftpServer.getHost() + ":" + ftpServer.getPort() + "/"
						+ ftpServer.getFileDir() + "?password="
						+ ftpServer.getPassword();
				if (buIfSchedule != null) {
					ftpUri += "&throwExceptionOnConnectFailed=true&localWorkDirectory="
							+ ftp.getFileCachePath()
							+ "&scheduler=quartz2&scheduler.cron="
							+ createTimer(buIfSchedule);
				} else {
					ftpUri += "&scheduler=quartz2&scheduler.cron="
							+ createTimer()
							+ "&throwExceptionOnConnectFailed=true&localWorkDirectory="
							+ ftp.getFileCachePath();
				}
				// 生成过滤文件的过滤条件
				if (ftpServer.getFileName() != null
						&& !ftpServer.getFileName().equals("")) {
					ftpUri += getFtpFileFilter(ftpServer.getFileName());
				}
				ftpUri += "&passiveMode=" + ftpMode + "&binary=true&disconnect=true&move=backup/${date:now:yyyyMMdd}/${file:name}";// &ftpClient.controlEncoding=gb2312&ftpFileFilter.regex=^re.*
				if(ftpServer.getControlEncoding()!=null&&!"".equals(ftpServer.getControlEncoding())){
					ftpUri+="&ftpClient.controlEncoding="+ftpServer.getControlEncoding();
				}
				if("1".equals(ftpServer.getIsDelSourceFile())){
					ftpUri+="&delete=true";
				}
			} else {// 如果是匿名登录，则生成没有password的uri
				// uri的样式如："ftp://lhlang@172.26.142.126:21?localWorkDirectory=E:/temp/&scheduler=quartz2&scheduler.cron=0/10 * * * * ?&fileName=report.txt&binary=true"
				ftpUri = "ftp://"
						+ ftpServer.getUserName()
						+ "@"
						+ ftpServer.getHost()
						+ ":"
						+ ftpServer.getPort()
						+ "/"
						+ ftpServer.getFileDir()
						+ "?binary=true"
						+ "&passiveMode=" + ftpMode + "&binary=true&disconnect=true&move=backup/${date:now:yyyyMMdd}/${file:name}";//&ftpClient.controlEncoding=gb2312";
				if(ftpServer.getControlEncoding()!=null&&!"".equals(ftpServer.getControlEncoding())){
					ftpUri+="&ftpClient.controlEncoding="+ftpServer.getControlEncoding();
				}
				if("1".equals(ftpServer.getIsDelSourceFile())){
					ftpUri+="&delete=true";
				}
				// 生成过滤文件的过滤条件
				if (ftpServer.getFileName() != null
						&& !ftpServer.getFileName().equals("")) {
					ftpUri += getFtpFileFilter(ftpServer.getFileName());
				}
				if (buIfSchedule != null) {
					ftpUri += "&throwExceptionOnConnectFailed=true&localWorkDirectory="
							+ ftp.getFileCachePath()
							+ "&scheduler=quartz2&scheduler.cron="
							+ createTimer(buIfSchedule);
				} else {
					ftpUri += "&throwExceptionOnConnectFailed=true&scheduler=quartz2&scheduler.cron="
							+ createTimer()
							+ "&localWorkDirectory="
							+ ftp.getFileCachePath();
				}
			}
		} else if (ftpServer.getHostType().equals("2")) {// 如果是目标ftp服务器，创建目标ftp服务的uri
			// 判断ftp的登录方式
			if (ftpServer.getIsAnonymous().equals("0")) {// 如果是非匿名登录，则生成含有password的uri
				// uri的样式如："ftp://lhlang@12.26.142.126:2112/?binary=true&password=111111"
				ftpUri = "ftp://"
						+ ftpServer.getUserName()
						+ "@"
						+ ftpServer.getHost()
						+ ":"
						+ ftpServer.getPort()
						+ "/"
						+ ftpServer.getFileDir()
						+ "?passiveMode=" + ftpMode + "&binary=true&password="//&ftpClient.controlEncoding=gb2312
						+ ftpServer.getPassword();
				if(ftpServer.getControlEncoding()!=null&&!"".equals(ftpServer.getControlEncoding())){
					ftpUri+="&ftpClient.controlEncoding="+ftpServer.getControlEncoding();
				}
			} else {// 如果是匿名登录，则生成没有password的uri
				// uri的样式如："ftp://lhlang@12.26.142.126:2112/?binary=true
				ftpUri = "ftp://" + ftpServer.getUserName() + "@"
						+ ftpServer.getHost() + ":" + ftpServer.getPort() + "/"
						+ ftpServer.getFileDir()
						+ "?binary=true&passiveMode=" + ftpMode;//&ftpClient.controlEncoding=gb2312";
				if(ftpServer.getControlEncoding()!=null&&!"".equals(ftpServer.getControlEncoding())){
					ftpUri+="&ftpClient.controlEncoding="+ftpServer.getControlEncoding();
				}
			}
		}
		return ftpUri;
	}

	/**
	 * 根据MethodName，fromServer，toServer生成bean中的method string
	 * 
	 * @param MethodName
	 *            方法名
	 * @param fromServer
	 *            源ftp服务
	 * @param toServer
	 *            目标ftp服务
	 * @return bean 的method 字符串
	 */
	public String getBeanMethod(String MethodName, FtpServer fromServer,
			FtpServer toServer) {
		String beanMethod = "";
		// method
		// 的样式：检验--"authResult(test, 172.26.142.126:21, 172.26.142.126:2112, ${file:name}, ${file:length})"
		// logbean--writeLog(test, test,172.26.142.126:21, 172.26.142.126:2112,
		// ${file:name}, ${file:length})
		beanMethod = MethodName + "(" + this.ftp.getCode() + ",";
		if (MethodName.equals("writeLog") || MethodName.equals("writeErrLog")) {
			beanMethod = beanMethod + this.ftp.getName() + "," + "";
		}
		beanMethod += fromServer.getHost() + ":" + fromServer.getPort() + ","
				+ toServer.getHost() + ":" + toServer.getPort()
				+ ", ${file:name}, ${file:length})";
		return beanMethod;
	}

	public String getBeanMethod(String MethodName, FtpServer fromServer) {
		String beanMethod = "";
		// method
		// 的样式：检验--"authResult(test, 172.26.142.126:21, 172.26.142.126:2112, ${file:name}, ${file:length})"
		// logbean--writeLog(test, test,172.26.142.126:21, 172.26.142.126:2112,
		// ${file:name}, ${file:length})
		beanMethod = MethodName + "(" + this.ftp.getCode() + ",";
		if (MethodName.equals("writeLog") || MethodName.equals("writeErrLog")) {
			beanMethod = beanMethod + this.ftp.getName() + "," + "";
		}
		beanMethod += fromServer.getHost() + ":" + fromServer.getPort() + ","
				+ "0.0.0.0" + ":" + "21" + ", ${file:name}, ${file:length})";
		return beanMethod;
	}

	/**
	 * @param buIfSchedule
	 *            定时任务
	 * @return 格式化的定时任务执行时间
	 */
	public String createTimer(TesbBuIfSchedule buIfSchedule) {
		String cron = "";
		// 周中的某天执行
		if (buIfSchedule.getRunCyc() == 1
				&& buIfSchedule.getRunWay().equals(
						KettleJobScheduleCycleUnit.Day.ValueCode)) {
			Calendar beginTime2 = Calendar.getInstance();
			beginTime2.setTime(buIfSchedule.getSkdBeginDate());
			int hour = beginTime2.get(Calendar.HOUR_OF_DAY);
			int minute = beginTime2.get(Calendar.MINUTE);

			Integer[] daysOfWeek = parseDaysOfWeek(buIfSchedule.getDayOfWeek());
			cron = CornExpressionUtil.atHourAndMinuteOnGivenDaysOfWeek(hour,
					minute, daysOfWeek);
		} else {

			if (buIfSchedule.getRunWay().equals(
					KettleJobScheduleCycleUnit.Second.ValueCode)) {
				// 每隔几秒执行一次
				cron = "0/" + buIfSchedule.getRunCyc() + " * * * * ?";

			}
			if (buIfSchedule.getRunWay().equals(
					KettleJobScheduleCycleUnit.Minute.ValueCode)) {
				// 每隔几分钟执行一次
				cron = "0 0/" + buIfSchedule.getRunCyc() + " * * * ? *";
			}
			if (buIfSchedule.getRunWay().equals(
					KettleJobScheduleCycleUnit.Hour.ValueCode)) {
				// 每隔几小时执行一次
				cron = "0 0 0/" + buIfSchedule.getRunCyc() + " * * ? *";
			}
			if (buIfSchedule.getRunWay().equals(
					KettleJobScheduleCycleUnit.Day.ValueCode)) {
				// 每隔几天执行一次
				cron = "0 0 0 1/" + buIfSchedule.getRunCyc() + " * ? *";
			}
			if (buIfSchedule.getRunWay().equals(
					KettleJobScheduleCycleUnit.Week.ValueCode)) {
				// 每隔几周执行一次
				cron = "0 0 0 0 0 1#" + buIfSchedule.getRunCyc();
			}
			if (buIfSchedule.getRunWay().equals(
					KettleJobScheduleCycleUnit.Month.ValueCode)) {
				// 每隔几月执行一次
				cron = "0 0 0 0 1/" + buIfSchedule.getRunCyc() + " ? *";
			}

			if (buIfSchedule.getRunWay().equals(
					KettleJobScheduleCycleUnit.Once.ValueCode)) {
				Date runTime = buIfSchedule.getSkdBeginDate();
				SimpleDateFormat sdf = new SimpleDateFormat(
						"yyyy/MM/dd/HH/mm/ss");
				String runTimeStr = sdf.format(runTime);
				String[] runTimeStrs = runTimeStr.split("/");
				cron = runTimeStrs[5] + " " + runTimeStrs[4] + " "
						+ runTimeStrs[3] + " " + runTimeStrs[2] + " "
						+ runTimeStrs[1] + " ? " + runTimeStrs[0];
			}
		}
		return cron;
	}

	public String createTimer() {
		String cron = "";
		Calendar calendar = Calendar.getInstance();
		calendar.setTimeInMillis(System.currentTimeMillis() + 5000);
		int year = calendar.get(Calendar.YEAR);
		int month = calendar.get(Calendar.MONTH) + 1;
		int date = calendar.get(Calendar.DATE);
		int hour = calendar.get(Calendar.HOUR_OF_DAY);
		int minute = calendar.get(Calendar.MINUTE);
		int second = calendar.get(Calendar.SECOND);
		cron = second + " " + minute + " " + hour + " " + date + " " + month
				+ " ? " + year;
		return cron;
	}

	/**
	 * 将stirng数组改成Integer数组
	 * 
	 * @param dayOfWeekStr
	 * @return
	 */
	private static Integer[] parseDaysOfWeek(String dayOfWeekStr) {
		dayOfWeekStr = '[' + dayOfWeekStr + ']';
		return new Gson().fromJson(dayOfWeekStr, Integer[].class);
	}

	/**
	 * 根据数据库的fileName生成过滤文件的条件
	 * 
	 * @param jsonStr
	 *            以json保存的过滤条件{"filterType":"1","checkStr":"^re.*"}
	 *            {"filterType":"2","checkStr":"report.txt,test.txt"}
	 * @return 过滤添加字符串
	 */
	private String getFtpFileFilter(String jsonStr) {
		Gson gson = new Gson();
		FileFilterJson fileFilterJson = gson.fromJson(jsonStr,
				FileFilterJson.class);
		// 如果FilterType=1，为正则表达式过滤
		if ("1".equals(fileFilterJson.getFilterType())) {
			return "&ftpFileFilter.regex=" + fileFilterJson.getCheckStr();
		} else {// 2，则是按给定文件名过滤
			return "&ftpFileFilter.fileNameStr=" + fileFilterJson.getCheckStr();
		}
	}

	public List<FtpServer> getFtpServersList() {
		return ftpServersList;
	}

	public void setFtpServersList(List<FtpServer> ftpServersList) {
		this.ftpServersList = ftpServersList;
	}

	public TesbBuIfSchedule getBuIfSchedule() {
		return buIfSchedule;
	}

	public void setBuIfSchedule(TesbBuIfSchedule buIfSchedule) {
		this.buIfSchedule = buIfSchedule;
	}

	public Ftp getFtp() {
		return ftp;
	}

	public void setFtp(Ftp ftp) {
		this.ftp = ftp;
	}

	public AuthServiceImpl getAuthServiceImpl() {
		return authServiceImpl;
	}

	public void setAuthServiceImpl(AuthServiceImpl authServiceImpl) {
		this.authServiceImpl = authServiceImpl;
	}

	public LogServiceImpl getLogServiceImpl() {
		return logServiceImpl;
	}

	public void setLogServiceImpl(LogServiceImpl logServiceImpl) {
		this.logServiceImpl = logServiceImpl;
	}

}
